﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

namespace CPPEI.Coolzon.Designer.Views
{
    public static class UIPartCommandManager
    {
        public static void Register(UIElement element)
        {
            Type customCommand = typeof(UIPartCommand);
            foreach (var property in customCommand.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static))
            {
                if (typeof(ICommand).IsAssignableFrom(property.PropertyType))
                {
                    var command = (ICommand)property.GetValue(null);
                    CommandBinding binding = new CommandBinding(command);
                    DefaultExecutedClassAttribute[] attrs = (DefaultExecutedClassAttribute[])property.GetCustomAttributes(typeof(DefaultExecutedClassAttribute), false);
                    if (attrs != null && attrs.Length > 0)
                    {
                        MethodInfo methodInfo = attrs[0].DefaultExecutedType.GetMethod("Executed");
                        if (methodInfo != null)
                        {
                            binding.Executed += (ExecutedRoutedEventHandler)methodInfo.CreateDelegate(typeof(ExecutedRoutedEventHandler));
                        }
                        methodInfo = attrs[0].DefaultExecutedType.GetMethod("CanExecute");
                        if (methodInfo != null)
                        {
                            binding.CanExecute += (CanExecuteRoutedEventHandler)methodInfo.CreateDelegate(typeof(CanExecuteRoutedEventHandler));
                        }
                    }
                    element.CommandBindings.Add(binding);
                }
            }
        }

        public static void Register(UIElement element, RoutedCommand command)
        {
            CommandBinding binding = new CommandBinding(command);
            PropertyInfo destPro = null;
            foreach (var propertyInfo in command.OwnerType.GetProperties(BindingFlags.Static | BindingFlags.Public))
            {
                if (propertyInfo.GetValue(null) == command)
                {
                    destPro = propertyInfo;
                    break;
                }
            }
            if (destPro == null)
            {
                throw new Exception("未找到该命令");
            }
            DefaultExecutedClassAttribute[] attrs = (DefaultExecutedClassAttribute[])destPro.GetCustomAttributes(typeof(DefaultExecutedClassAttribute), false);
            if (attrs != null && attrs.Length > 0)
            {
                MethodInfo methodInfo = attrs[0].DefaultExecutedType.GetMethod("Executed");
                if (methodInfo != null)
                {
                    binding.Executed += (ExecutedRoutedEventHandler)methodInfo.CreateDelegate(typeof(ExecutedRoutedEventHandler));
                }
                methodInfo = attrs[0].DefaultExecutedType.GetMethod("CanExecute");
                if (methodInfo != null)
                {
                    binding.CanExecute += (CanExecuteRoutedEventHandler)methodInfo.CreateDelegate(typeof(CanExecuteRoutedEventHandler));
                }
            }
            element.CommandBindings.Add(binding);
        }

        public static void Register(UIElement element, string command)
        {
            Type customCommand = typeof(UIPartCommand);
            PropertyInfo propertyInfo = customCommand.GetProperty(command);
            CommandBinding binding = new CommandBinding((ICommand)propertyInfo.GetValue(null));
            DefaultExecutedClassAttribute[] attrs = (DefaultExecutedClassAttribute[])propertyInfo.GetCustomAttributes(typeof(DefaultExecutedClassAttribute), false);
            if (attrs != null && attrs.Length > 0)
            {
                MethodInfo methodInfo = attrs[0].DefaultExecutedType.GetMethod("Executed");
                if (methodInfo != null)
                {
                    binding.Executed += (ExecutedRoutedEventHandler)methodInfo.CreateDelegate(typeof(ExecutedRoutedEventHandler));
                }
                methodInfo = attrs[0].DefaultExecutedType.GetMethod("CanExecute");
                if (methodInfo != null)
                {
                    binding.CanExecute += (CanExecuteRoutedEventHandler)methodInfo.CreateDelegate(typeof(CanExecuteRoutedEventHandler));
                }
            }
            element.CommandBindings.Add(binding);
        }

        public static void Register(UIElement element, ICommand command, ExecutedRoutedEventHandler executed, CanExecuteRoutedEventHandler canExecute)
        {
            CommandBinding binding = new CommandBinding(command, executed, canExecute);
            element.CommandBindings.Add(binding);
        }
    }
}
